from tcplink import linkDev,GatController
import json
from ipphone import SIPClient
import threading
import os
import paho.mqtt.client as mqtt
import time


tcpsrv = linkDev("192.168.1.8",4242)
tcpsrv.start()
time.sleep(2)

master = GatController("192.168.1.100",4242)

def tcp_send(cmd):
    if master.connect():
        master.send_text(cmd+"\n")
        return True
    else:
        return False
    
class mqttControl:
    def __init__(self,host="192.168.1.100",port=1883):
        # sip服务器设置
        self.SIP_SERVER = "192.168.1.150"    # SIP服务器IP
        self.SIP_PORT = 5060                 # SIP服务器端口
        self.USERNAME = "8001"               # 注册账号
        self.PASSWORD = "1234"               # 账号密码
        self.AUDIO_FILE = "audio.wav"        # 音频文件路径（确保存在）
        if not os.path.exists(self.AUDIO_FILE):
            print(f"❌ 错误: 音频文件不存在 - {self.AUDIO_FILE}")
            print("请修改AUDIO_FILE为正确路径（推荐16bit/单声道WAV）")
        # 设备信息 - 更新为闸机控制器
        self.vin = "ROBOT-SIM"  # 可以根据需要修改为ZJZK-SIM
        self.terminal_id = 3    # 闸机主控
        self.frame_id = 0      
        # 初始化状态标记
        self.dt_state_initialized = False
        self.dt_men_state_initialized = False
        self.initial_close_door_executed = False

        # MQTT配置
        self.mqtt_client = mqtt.Client()
        self.mqtt_client.on_connect = self.on_mqtt_connect
        self.mqtt_client.on_message = self.on_mqtt_message

        # MQTT配置
        self.mqtt_client = mqtt.Client()
        self.mqtt_client.on_connect = self.on_mqtt_connect
        self.mqtt_client.on_message = self.on_mqtt_message
        
        # 从ROS参数获取MQTT配置
        self.mqtt_host = host
        self.mqtt_port = port
        # 连接MQTT代理
        try:
            self.mqtt_client.connect(self.mqtt_host, self.mqtt_port, 60)
            self.mqtt_client.loop_start()
        except Exception as e:
            print(f"MQTT连接失败: {e}")
        print("SlidingDoorController 已启动，提供电梯门和闸机门控制服务，支持ROS服务和MQTT控制")

        # 创建客户端并执行呼叫
        self.client = SIPClient(
            sip_server=self.SIP_SERVER,
            sip_port=self.SIP_PORT,
            username=self.USERNAME,
            password=self.PASSWORD,
            audio_file=self.AUDIO_FILE
        )

    def on_mqtt_connect(self, client, userdata, flags, rc):
        """MQTT连接回调"""
        if rc == 0:
            print("MQTT连接成功")
            # 订阅电梯任务主题和闸机任务主题
            client.subscribe("dt/task_manager")
            # client.subscribe("zj/task_manager")
            print("已订阅主题: dt/task_manager, zj/task_manager")
        else:
            print(f"MQTT连接失败，错误码: {rc}")

    def on_mqtt_message(self, client, userdata, msg):
        """MQTT消息回调"""
        try:
            payload = json.loads(msg.payload.decode())
            print(f"收到MQTT消息: {payload}")
            # 检查消息格式
            if not self.validate_message(payload):
                return
            if payload.get("VIN") == "ROBOT-SIM":
                return            
            # 处理电梯控制指令 (sys_data_type = 1006)
            if payload.get("sys_data_type") == 1006:
                self.handle_elevator_control(payload)            
            # 处理闸机控制指令 (sys_data_type = 1005)
            elif payload.get("sys_data_type") == 1005:
                self.handle_gate_control(payload)
            elif payload.get("sys_data_type") == 1007:
                self.handle_callphone_control(payload)                
        except json.JSONDecodeError as e:
            print(f"JSON解析错误: {e}")
        except Exception as e:
            print(f"处理MQTT消息时发生错误: {e}")

    def validate_message(self, payload):
        """验证消息格式"""
        required_fields = ["VIN", "terminal_id", "frame_id", "sys_data_type", "time_stamp", "code", "data"]
        for field in required_fields:
            if field not in payload:
                print(f"消息缺少必要字段: {field}")
                return False
        return True
    
    def handle_elevator_control(self, payload):
        """处理电梯控制指令"""
        try:
            data = payload.get("data", {})
            task_type = data.get("tasktype")
            task_id = data.get("task_id")
            
            response_data = {
                "task_status": 1,  # 1=接收任务
                "error_code": 0,
                "task_id": task_id
            }            
            if task_type == 1:  # 开门
                print(f"收到开门指令，任务ID: {task_id}")
                # 在单独线程中执行开门操作，避免阻塞MQTT
                threading.Thread(target=self._execute_open_door, args=(task_id,)).start()
            elif task_type == 2:  # 关门
                print(f"收到关门指令，任务ID: {task_id}")
                # 在单独线程中执行关门操作，避免阻塞MQTT
                threading.Thread(target=self._execute_close_door, args=(task_id,)).start()
            elif task_type == 3:  # 呼叫电梯
                threading.Thread(target=self._call_elecator, args=(task_id,data.get("current_floor"))).start()
                time.sleep(3)
            elif task_type == 4:  # 按电梯
                threading.Thread(target=self._press_elecator, args=(task_id,data.get("target_floor"))).start()
                time.sleep(3)
            else:
                print(f"未知的任务类型: {task_type}")
                response_data["task_status"] = 3  # 任务失败
                response_data["error_code"] = 1            
            # 发送任务接收确认
            self.send_mqtt_response(payload, response_data)
            
        except Exception as e:
            print(f"处理电梯控制指令时发生错误: {e}")
            response_data = {
                "task_status": 3,  # 任务失败
                "error_code": 1,
                "task_id": data.get("task_id", 0)
            }
            self.send_mqtt_response(payload, response_data)

    def handle_callphone_control(self, payload):
        "处理电话控制命令"
        try:
            data = payload.get("data", {})
            task_type = data.get("tasktype")
            point_id = data.get("point_id")
            print("开始电话控制指令")
            self._execute_call_phone(point_id)
            print("处理电话控制指令成功")
            response_data = {
                "task_status": 1,  # 任务失败
                "error_code": 1,
                "task_id": data.get("task_id", 0)
            }
        except Exception as e:
            print(f"处理电话控制指令时发生错误: {e}")
            response_data = {
                "task_status": 3,  # 任务失败
                "error_code": 1,
                "task_id": data.get("task_id", 0)
            }
        self.send_mqtt_response(payload, response_data)

    def handle_gate_control(self, payload):
        """处理闸机控制指令"""
        try:
            data = payload.get("data", {})
            task_type = data.get("tasktype")
            task_id = data.get("task_id")
            
            response_data = {
                "task_status": 1,  # 1=接收任务
                "error_code": 0,
                "task_id": task_id
            }
            
            if task_type == 1:  # 开闸机门
                print(f"收到开闸机门指令，任务ID: {task_id}")
                # 在单独线程中执行开门操作，避免阻塞MQTT
                threading.Thread(target=self._execute_open_gate, args=(task_id,)).start()
                
            elif task_type == 2:  # 关闸机门
                print(f"收到关闸机门指令，任务ID: {task_id}")
                # 在单独线程中执行关门操作，避免阻塞MQTT
                threading.Thread(target=self._execute_close_gate, args=(task_id,)).start()
                
            else:
                print(f"未知的闸机任务类型: {task_type}")
                response_data["task_status"] = 3  # 任务失败
                response_data["error_code"] = 1
            
            # 发送任务接收确认
            self.send_mqtt_response(payload, response_data)
        except Exception as e:
            print(f"处理闸机控制指令时发生错误: {e}")
            response_data = {
                "task_status": 3,  # 任务失败
                "error_code": 1,
                "task_id": data.get("task_id", 0)
            }
            self.send_mqtt_response(payload, response_data)

    def _execute_call_phone(self,point_id):
        """执行初始电话操作"""
        try:
            print(f"正在拨打房间：{point_id}电话")
            phoneNum = {"201":8000,"202":8002,"301":8003,"302":8004}
            self.client.start_call_sequence(phoneNum[point_id])
            response_data = {
                "task_status": 2,  # 任务成功
                "error_code": 0,
                "task_id": point_id
            }
            print(f"房间：{point_id}电话已经挂断")
        except Exception as e:
            print(f"拨打房间：{point_id}电话失败: {e}")
            response_data = {
                "task_status": 2,  # 任务失败
                "error_code": 0,
                "task_id": point_id
            }
        time.sleep(1)
        self.send_task_completion_response(point_id, response_data)

    def _execute_open_door(self,task_id,timeout=4):
        """执行初始开门操作"""
        try:
            if tcp_send("eo"):
                time.sleep(timeout)
                response_data = {
                    "task_status": 2,  # 任务成功
                    "error_code": 0,
                    "task_id": task_id
                }
                print("门已开启")
            else:
                response_data = {
                    "task_status": 3,  # 任务失败
                    "error_code": 0,
                    "task_id": task_id
                }
            
            self.send_task_completion_response(task_id, response_data)
        except Exception as e:
            print(f"初始开门操作失败: {e}")
            response_data = {
                "task_status": 3,  # 任务失败
                "error_code": 0,
                "task_id": task_id
            }
            self.send_task_completion_response(task_id, response_data)

    def _execute_close_door(self,task_id,timeout=4):
        """执行初始关门操作"""
        try:
            if tcp_send("ec"):
                response_data = {
                    "task_status": 2,  # 任务成功
                    "error_code": 0,
                    "task_id": task_id
                }
                print("门已关闭")
                time.sleep(timeout)
            else:
                response_data = {
                    "task_status": 3,  # 任务失败
                    "error_code": 0,
                    "task_id": task_id
                }            
            self.send_task_completion_response(task_id, response_data)
        except Exception as e:
            print(f"初始关门操作失败: {e}")
            response_data = {
                "task_status": 3,  # 任务失败
                "error_code": 0,
                "task_id": task_id
            }
            self.send_task_completion_response(task_id, response_data)

    def _call_elecator(self, task_id, floor,timeout=10):
        """呼叫电梯"""
        try:
            # 呼叫电梯 延时2s
            print(f"呼叫电梯 到{floor}层 ")
            if tcp_send(str(floor)):
                time.sleep(timeout)

                print("呼叫电梯操作成功")
                response_data = {
                    "task_status": 2,  # 任务成功
                    "error_code": 0,
                    "task_id": task_id
                }
            else:
                response_data = {
                    "task_status": 3,  # 任务失败
                    "error_code": 0,
                    "task_id": task_id
                } 
            print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
            print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
            print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
            print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
            print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
            print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
            self.send_task_completion_response(task_id, response_data)
        except Exception as e:
            print(f"呼叫电梯操作失败: {e}")
            response_data = {
                "task_status": 3,  # 任务失败
                "error_code": 1,
                "task_id": task_id
            }
            self.send_task_completion_response(task_id, response_data)

    def _press_elecator(self, task_id, floor):
        """按电梯"""
        try:
            # 呼叫电梯 延时2s
            print(f"呼叫电梯 到{floor}层 ")
            if tcp_send(str(floor)):
                time.sleep(5)

                print("呼叫电梯操作成功")
                response_data = {
                    "task_status": 2,  # 任务成功
                    "error_code": 0,
                    "task_id": task_id
                }
            else:
                response_data = {
                    "task_status": 3,  # 任务失败
                    "error_code": 0,
                    "task_id": task_id
                } 
            print("**************************************************************")
            print("**************************************************************")
            print("**************************************************************")
            print("**************************************************************")
            self.send_task_completion_response(task_id, response_data)
        except Exception as e:
            print(f"呼叫电梯操作失败: {e}")
            response_data = {
                "task_status": 3,  # 任务失败
                "error_code": 1,
                "task_id": task_id
            }
            self.send_task_completion_response(task_id, response_data)

    def send_mqtt_response(self, original_payload, response_data):
        """发送MQTT响应"""
        self.frame_id += 1
        response = {
            "VIN": self.vin,
            "terminal_id": self.terminal_id,
            "frame_id": self.frame_id,
            "sys_data_type": original_payload.get("sys_data_type"),
            "time_stamp": int(time.time() * 1000),
            "code": 0,  # 响应成功
            "data": response_data
        }
        try:
            # 根据消息类型选择正确的主题
            sys_data_type = original_payload.get("sys_data_type")
            # if sys_data_type == 1005:  # 闸机控制指令
            #     topic = "zj/task_manager"
            # elif sys_data_type == 1006:  # 电梯控制指令
            #     topic = "dt/task_manager"
            # else:
            topic = "dt/task_manager"  # 默认主题
                
            self.mqtt_client.publish(topic, json.dumps(response))
            print(f"已发送MQTT响应到主题 {topic}: {response}")
        except Exception as e:
            print(f"发送MQTT响应失败: {e}")

    def send_mqtt_response(self, original_payload, response_data):
        """发送MQTT响应"""
        self.frame_id += 1
        response = {
            "VIN": self.vin,
            "terminal_id": self.terminal_id,
            "frame_id": self.frame_id,
            "sys_data_type": original_payload.get("sys_data_type"),
            "time_stamp": int(time.time() * 1000),
            "code": 0,  # 响应成功
            "data": response_data
        }
        
        try:
            # 根据消息类型选择正确的主题
            sys_data_type = original_payload.get("sys_data_type")
            # if sys_data_type == 1005:  # 闸机控制指令
            #     topic = "zj/task_manager"
            # elif sys_data_type == 1006:  # 电梯控制指令
            #     topic = "dt/task_manager"
            # else:
            topic = "dt/task_manager"  # 默认主题
                
            self.mqtt_client.publish(topic, json.dumps(response))
            print(f"已发送MQTT响应到主题 {topic}: {response}")
        except Exception as e:
            print(f"发送MQTT响应失败: {e}")

    def send_task_completion_response(self, task_id, response_data):
        """发送任务完成响应"""
        self.frame_id += 1
        response = {
            "VIN": self.vin,
            "terminal_id": self.terminal_id,
            "frame_id": self.frame_id,
            "sys_data_type": 1006,  # 电梯控制指令
            "time_stamp": int(time.time() * 1000),
            "code": 0,  # 响应成功
            "data": response_data
        }
        try:
            topic = "dt/task_manager"
            self.mqtt_client.publish(topic, json.dumps(response))
            print(f"已发送任务完成响应: {response}")
        except Exception as e:
            print(f"发送任务完成响应失败: {e}")
        
    def _execute_open_gate(self, task_id,timeout=3):
        """执行开闸机门操作"""
        try:
            print("正在开闸机门...")
            if tcp_send("go"):
                time.sleep(timeout)
                print("闸机门已打开")
                # 发送任务成功响应
                response_data = {
                    "task_status": 2,  # 任务成功
                    "error_code": 0,
                    "task_id": task_id
                }
            else:
                print("闸机门打开失败")
                # 发送任务成功响应
                response_data = {
                    "task_status": 3,  # 任务失败
                    "error_code": 0,
                    "task_id": task_id
                }
            self.send_gate_completion_response(task_id, response_data)
        except Exception as e:
            print(f"开闸机门操作失败: {e}")
            response_data = {
                "task_status": 3,  # 任务失败
                "error_code": 1,
                "task_id": task_id
            }
            self.send_gate_completion_response(task_id, response_data)
        

    def _execute_close_gate(self, task_id,timeout=3):
        """执行关闸机门操作"""
        try:
            print("正在关闸机门...")
            if tcp_send("gc"): 
                time.sleep(timeout)
                print("闸机门已关闭")
                # 发送任务成功响应
                response_data = {
                    "task_status": 2,  # 任务成功
                    "error_code": 0,
                    "task_id": task_id
                }
            else:
                print("闸机门关闭失败")
                # 发送任务成功响应
                response_data = {
                    "task_status": 3,  # 任务失败
                    "error_code": 0,
                    "task_id": task_id
                }
            
        except Exception as e:
            print(f"关闸机门操作失败: {e}")
            response_data = {
                "task_status": 3,  # 任务失败
                "error_code": 1,
                "task_id": task_id
            }
        self.send_gate_completion_response(task_id, response_data)

    def send_gate_completion_response(self, task_id, response_data):
        """发送闸机任务完成响应"""
        self.frame_id += 1
        response = {
            "VIN": self.vin,
            "terminal_id": self.terminal_id,
            "frame_id": self.frame_id,
            "sys_data_type": 1005,  # 闸机控制指令
            "time_stamp": int(time.time() * 1000),
            "code": 0,  # 响应成功
            "data": response_data
        }
        
        try:
            topic = "dt/task_manager"
            self.mqtt_client.publish(topic, json.dumps(response))
            print(f"已发送闸机任务完成响应: {response}")
        except Exception as e:
            print(f"发送闸机任务完成响应失败: {e}")

    def shutdown(self):
        """关闭MQTT连接"""
        try:
            self.mqtt_client.loop_stop()
            self.mqtt_client.disconnect()
            self.client.cleanup(force=True)
            print("MQTT连接已断开")
        except Exception as e:
            print(f"断开MQTT连接时发生错误: {e}")







if __name__ == "__main__":
    try:
        # tcp_send("gc")
        # tcp_send("ec")
        mt = mqttControl()
        while(1):
            time.sleep(1)
    finally:
        mt.shutdown()
        tcpsrv.close()
        master.close()